package com.meego.common.mail;

import com.meego.common.config.Config;
import com.meego.common.log.GA;
import com.meego.common.util.StringUtils;
import java.io.File;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 * Send an Email via Gmail SMTP server using TLS connection
 *
 * @author Hoang Minh Tue (minhtue0402@yahoo.com)
 *
 */
public class SendMailTLS {

    private static SendMailTLS instance;
    private String username;
    private String password;
    private Properties props;

    public static SendMailTLS getInstance() {
        if (instance == null) {
            instance = new SendMailTLS();
        }
        return instance;
    }

    private SendMailTLS() {
        username = Config.getStrConfig("vs.mail.username", "");
        password = Config.getStrConfig("vs.mail.password", "");
        if (username.isEmpty() || password.isEmpty()) {
            GA.mail.info("Config FAIL: [vs.mail.username/vs.mail.password: <null> or empty]");
        }
        props = new Properties();
        props.put("mail.smtp.auth", Config.getStrConfig("vs.mail.smtp.auth", "true"));
        props.put("mail.smtp.starttls.enable", Config.getStrConfig("vs.mail.smtp.starttls.enable", "true"));
        props.put("mail.smtp.host", Config.getStrConfig("vs.mail.smtp.host", "smtp.gmail.com"));
        props.put("mail.smtp.port", Config.getStrConfig("vs.mail.smtp.tls.port", "587"));
    }

    /**
     * Send Email via Gmail SMTP server using TLS connection with plain text
     * content.
     *
     * @param to list email address will be sent to (distinguished by
     * comma(<b>,</b>))
     * @param subject
     * @param content (plain text)
     * @param attachments
     */
    public void sendText(String to, String subject, String content, List<String> attachments) throws RuntimeException {
        Session session = Session.getInstance(props, new javax.mail.Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        try {

            List<String> list = StringUtils.toList(to, ";");
            for (String string : list) {
                Message message = new MimeMessage(session);
                message.setFrom(new InternetAddress(Config.getStrConfig("vs.mail.from", username)));
                message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(string));
                message.setSubject(subject);
                if (attachments == null || attachments.isEmpty()) {
                    message.setText(content);
                } else {
                    // Create the message part 
                    BodyPart messageBodyPart = new MimeBodyPart();
                    // Fill the message
                    messageBodyPart.setText(content);

                    // Create a multipar message
                    Multipart multipart = new MimeMultipart();

                    // Set text message part
                    multipart.addBodyPart(messageBodyPart);

                    for (String entry : attachments) {
                        try {
                            // Part two is attachment
                            messageBodyPart = new MimeBodyPart();
                            String filename = "";
                            try {
                                filename = entry.substring(entry.lastIndexOf(File.separator) + 1);
                            } catch (Exception e) {
                            }
                            DataSource source = new FileDataSource(entry);
                            messageBodyPart.setDataHandler(new DataHandler(source));
                            messageBodyPart.setFileName(filename.isEmpty() ? entry : filename);
                            multipart.addBodyPart(messageBodyPart);
                        } catch (Exception e) {
                            GA.mail.error("Add Attachment to mail message FAIL", e);
                        }
                    }

                    // Send the complete message parts
                    message.setContent(multipart);
                }

                Transport.send(message);
            }

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Send Email via Gmail SMTP server using TLS connection with HTML content.
     *
     * @param to list email address will be sent to (distinguished by
     * comma(<b>,</b>))
     * @param subject
     * @param content (text/html)
     * @param attachments
     */
    public void sendHTML(String to, String subject, String content, List<String> attachments) throws RuntimeException {
        Session session;
        session = Session.getInstance(props, new javax.mail.Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        try {
            List<String> list = StringUtils.toList(to, ";");
            for (String string : list) {
                Message message = new MimeMessage(session);
                message.setFrom(new InternetAddress(Config.getStrConfig("vs.mail.from", username)));
                message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(string));
                message.setSubject(subject);
                if (attachments == null || attachments.isEmpty()) {
                    message.setContent(content, "text/html");
                } else {
                    // Create the message part 
                    BodyPart messageBodyPart = new MimeBodyPart();
                    // Fill the message
                    messageBodyPart.setContent(content, "text/html");

                    // Create a multipar message
                    Multipart multipart = new MimeMultipart();

                    // Set text message part
                    multipart.addBodyPart(messageBodyPart);

                    for (String entry : attachments) {
                        try {
                            // Part two is attachment
                            messageBodyPart = new MimeBodyPart();
                            String filename = "";
                            try {
                                filename = entry.substring(entry.lastIndexOf(File.separator) + 1);
                            } catch (Exception e) {
                            }
                            DataSource source = new FileDataSource(entry);
                            messageBodyPart.setDataHandler(new DataHandler(source));
                            messageBodyPart.setFileName(filename.isEmpty() ? entry : filename);
                            multipart.addBodyPart(messageBodyPart);
                        } catch (Exception e) {
                            GA.mail.error("Add Attachment to mail message FAIL", e);
                        }
                    }

                    // Send the complete message parts
                    message.setContent(multipart);
                }

                Transport.send(message);
            }

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}